package servidor;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;

import jugador.PuntoJugador;



public class Servidor5 {
static final int PUERTO=4999; //puerto en el cual escucho a los clientes
	
	ArrayList<Socket> listaClientes;
	ArrayList<PuntoJugador> listaPuntos;
	int x,y;
	
	
	public Servidor5(){
		System.out.println("Escucho en el puerto :"+PUERTO);
		listaClientes = new ArrayList<Socket>();
		listaPuntos = new ArrayList<PuntoJugador>();
		x=0;
		y=0;
		
		try {
			//Creo un socket que escucha a los clientes en  PUERTO
			ServerSocket skServidor = new ServerSocket( PUERTO );
			
			Runnable hablaCliente = new HiloHablaClientes();
			Thread hiloHabla = new Thread(hablaCliente);
			hiloHabla.start();	
			
			//se crea un ciclo permanente para escuchar a todos los clientes que lleguen
			while(true){
				//se crea un socket por cada cliente que llegue y se crea un hilo que lo atienda
				Socket skCliente = skServidor.accept();
				//agrego el nuevo cliente la lista de clientes
				listaClientes.add(skCliente);
				listaPuntos.add(new PuntoJugador());
				
				Runnable nuevoCliente = new HiloAtiendeCliente(skCliente);
				Thread hilo = new Thread(nuevoCliente);
				hilo.start();
				
				
				
				System.out.println("LLEGO UN CLIENTE");
				
			}
	
		} 
		catch( Exception e ) {
	
			System.out.println( e.getMessage() );
	
		}
		
		
	}
	public class HiloHablaClientes implements Runnable {
		public void run() {
			
			try {
				double tiempo = System.currentTimeMillis();
				while(true){
					
					Thread.sleep(20);
					tiempo = (System.currentTimeMillis()-tiempo)/1000f;
					Iterator i = listaPuntos.iterator();
					Iterator j;
					Socket socket;
					PuntoJugador puntoJugador; 
					DataOutputStream flujoSalida;
					int numPunto=0;
					while(i.hasNext()){
						puntoJugador=((PuntoJugador) i.next());
						puntoJugador.actualizar(tiempo);
						j = listaClientes.iterator();
						while(j.hasNext()){
							
							socket = (Socket)j.next();
							OutputStream aux = socket.getOutputStream();
							flujoSalida= new DataOutputStream( aux );
							
							flujoSalida.writeUTF(""+numPunto);
							
							flujoSalida.writeUTF(""+puntoJugador.getxActual());
							flujoSalida.writeUTF(""+puntoJugador.getyActual());
							
						}
						//
						System.out.println(numPunto);
						numPunto++;
					}
					tiempo = System.currentTimeMillis();
				}
				
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
	
	
	private class HiloAtiendeCliente implements Runnable{
		
		DataInputStream flujoEntrada; 
		DataOutputStream flujoSalida;
		
		public HiloAtiendeCliente(Socket socket){
			
			try {
				
				InputStream aux = socket.getInputStream();
				//genera el flujo de entrada, por aca RECIBO los mensajes que vienen de este cliente
				flujoEntrada = new DataInputStream( aux );
				OutputStream aux1 = socket.getOutputStream();
				flujoSalida =  new DataOutputStream(aux1);
				//le envio el id de cliente que esta eperando
				flujoSalida.writeUTF(""+(listaClientes.size()-1));
				
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			
			
			
		}
		@Override
		public void run() {
			int idCliente;
			//creo un lazo que esta continuamente esperando mensajes del cliente al que atiende
			while(true){
				try {
					System.out.println("Espero Coordenadas x,y");
					//asumo que los mensajes se envian en este orden, primero x y luego y
					idCliente=Integer.parseInt(flujoEntrada.readUTF());
					x=Integer.parseInt(flujoEntrada.readUTF());
					y=Integer.parseInt(flujoEntrada.readUTF());
					
					listaPuntos.get(idCliente).asignarPosicionDeseada(x, y);
					System.out.println("SERVIDOR: "+idCliente +" X: "+x+" Y: "+y);
					for(int i=0;i<listaPuntos.size();i++){
						
						System.out.println("Punto "+i+" X: "+listaPuntos.get(i).getxActual()+" Y: "+listaPuntos.get(i).getyActual());
					}
					//despues de recibir una actualizacion , actualizo a todos los demas clientes
					//actualizarClientes(idCliente);
					
				} catch (NumberFormatException | IOException e) {
					
					e.printStackTrace();
				}
			}
			
		}
	}
	
	public static void main(String[] args) {
		
		new Servidor5();
		
	}

	

}
